/*******************************************************************************
* Copyright 2019 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/

#include "common_f32.hpp"
#include "jit_generator.hpp"

namespace mkldnn {
namespace impl {
namespace cpu {

jit_avx2_f32_copy_bt_kern::jit_avx2_f32_copy_bt_kern() :
    jit_generator(nullptr, F32_COPY_KERNEL_CODE_SIZE) {

#ifndef _WIN32
#define M   rdi
#define N   rsi
#define A   rdx
#define LDA rcx
#define ALPHA   r8
#define B   r9

#define I   rax
#define A1  r10
#define A2  r8
#define LDA3    r11

#else
#define M   rcx
#define N   rdx
#define A   r8
#define LDA r9
#define ALPHA   rsi
#define B   rdi
#define I   rax
#define A1  rsi
#define A2  r10
#define LDA3    r11

#define ARG_ALPHA   40+stacksize+rsp
#define ARG_B       48+stacksize+rsp

#endif

inLocalLabel();
{

Xbyak::Label l124;
Xbyak::Label l150;
Xbyak::Label l16c;
Xbyak::Label l17c;
Xbyak::Label l19c;
Xbyak::Label l214;
Xbyak::Label l258;
Xbyak::Label l284;
Xbyak::Label l2a0;
Xbyak::Label l2a4;
Xbyak::Label l2c4;
Xbyak::Label l33c;
Xbyak::Label l380;
Xbyak::Label l3ac;
Xbyak::Label l3c8;
Xbyak::Label l3cc;
Xbyak::Label l3d4;
Xbyak::Label l3f0;
Xbyak::Label l408;
Xbyak::Label l4a4;
Xbyak::Label l4f8;
Xbyak::Label l52c;
Xbyak::Label l54;
Xbyak::Label l54c;
Xbyak::Label l55c;
Xbyak::Label l580;
Xbyak::Label l61c;
Xbyak::Label l670;
Xbyak::Label l68;
Xbyak::Label l6a4;
Xbyak::Label l6c4;
Xbyak::Label l6c8;
Xbyak::Label l6ec;
Xbyak::Label l788;
Xbyak::Label l7dc;
Xbyak::Label l810;
Xbyak::Label l830;
Xbyak::Label l834;
Xbyak::Label l83c;
Xbyak::Label l848;
Xbyak::Label l860;
Xbyak::Label l8fc;
Xbyak::Label l950;
Xbyak::Label l984;
Xbyak::Label l9a4;
Xbyak::Label l9b4;
Xbyak::Label l9d8;
Xbyak::Label la74;
Xbyak::Label lac8;
Xbyak::Label lafc;
Xbyak::Label lb1c;
Xbyak::Label lb20;
Xbyak::Label lb44;
Xbyak::Label lbe0;
Xbyak::Label lc34;
Xbyak::Label lc68;
Xbyak::Label lc88;
Xbyak::Label lc8c;
Xbyak::Label le0;

    preamble();
#ifdef _WIN32
    auto stacksize = get_size_of_abi_save_regs();
    mov(ALPHA, ptr[ARG_ALPHA]);
    mov(B, ptr[ARG_B]);
#endif

    mov(M, qword[M]);
    mov(N, qword[N]);
    mov(LDA, qword[LDA]);
    sub(A, -128);
    sub(B, -128);
    shl(LDA, 0x2);
    lea(LDA3, ptr[LDA+LDA*2]);
    vbroadcastss(ymm6, dword[ALPHA]);
    vpcmpeqb(xmm3, xmm3, xmm3);
    vpsrld(xmm3, xmm3, 0x17);
    vpslld(xmm3, xmm3, 0x19);
    vpsrld(xmm3, xmm3, 0x2);
    vpcmpeqb(xmm4, xmm4, xmm4);
    vpslld(xmm4, xmm4, 0x1f);
    vperm2f128(ymm4, ymm4, ymm4, 0x20);
    vucomiss(xmm6, xmm3);
    jne(l3d4, T_NEAR);
    cmp(N, 0x4);
    jl(l17c, T_NEAR);
    align(4);

L(l54);
    mov(A1, A);
    lea(A2, ptr[A1+LDA*4]);
    add(A, 0x10);
    mov(I, M);
    sar(I, 0x3);
    jle(le0, T_NEAR);
    align(4);

L(l68);
    vmovups(xmm0, xword[A1-0x80]);
    vmovups(xword[B-0x80], xmm0);
    vmovups(xmm0, xword[A1+LDA*1-0x80]);
    vmovups(xword[B-0x70], xmm0);
    vmovups(xmm0, xword[A1+LDA*2-0x80]);
    vmovups(xword[B-0x60], xmm0);
    vmovups(xmm0, xword[A1+LDA3*1-0x80]);
    vmovups(xword[B-0x50], xmm0);
    vmovups(xmm0, xword[A2-0x80]);
    vmovups(xword[B-0x40], xmm0);
    vmovups(xmm0, xword[A2+LDA*1-0x80]);
    vmovups(xword[B-0x30], xmm0);
    vmovups(xmm0, xword[A2+LDA*2-0x80]);
    vmovups(xword[B-0x20], xmm0);
    vmovups(xmm0, xword[A2+LDA3*1-0x80]);
    vmovups(xword[B-0x10], xmm0);
    lea(A1, ptr[A1+LDA*8]);
    lea(A2, ptr[A2+LDA*8]);
    sub(B, -128);
    dec(I);
    jg(l68, T_NEAR);
    align(4);

L(le0);
    test(M, 0x4);
    jle(l124, T_NEAR);
    vmovups(xmm0, xword[A1-0x80]);
    vmovups(xword[B-0x80], xmm0);
    vmovups(xmm0, xword[A1+LDA*1-0x80]);
    vmovups(xword[B-0x70], xmm0);
    vmovups(xmm0, xword[A1+LDA*2-0x80]);
    vmovups(xword[B-0x60], xmm0);
    vmovups(xmm0, xword[A1+LDA3*1-0x80]);
    vmovups(xword[B-0x50], xmm0);
    lea(A1, ptr[A1+LDA*4]);
    sub(B, -64);
    align(4);

L(l124);
    test(M, 0x2);
    jle(l150, T_NEAR);
    vmovups(xmm0, xword[A1-0x80]);
    vmovups(xword[B-0x80], xmm0);
    vmovups(xmm0, xword[A1+LDA*1-0x80]);
    vmovups(xword[B-0x70], xmm0);
    lea(A1, ptr[A1+LDA*2]);
    sub(B, -32);
    align(4);

L(l150);
    test(M, 0x1);
    jle(l16c, T_NEAR);
    vmovups(xmm0, xword[A1-0x80]);
    vmovups(xword[B-0x80], xmm0);
    sub(B, -16);
    align(4);

L(l16c);
    sub(N, 0x4);
    cmp(N, 0x4);
    jge(l54, T_NEAR);
    align(4);

L(l17c);
    cmp(N, 0x2);
    jl(l2a4, T_NEAR);
    mov(A1, A);
    lea(A2, ptr[A1+LDA*4]);
    add(A, 0x8);
    mov(I, M);
    sar(I, 0x3);
    jle(l214, T_NEAR);
    align(4);

L(l19c);
    vmovsd(xmm0, qword[A1-0x80]);
    vmovlps(qword[B-0x80], xmm0);
    vmovsd(xmm0, qword[A1+LDA*1-0x80]);
    vmovlps(qword[B-0x78], xmm0);
    vmovsd(xmm0, qword[A1+LDA*2-0x80]);
    vmovlps(qword[B-0x70], xmm0);
    vmovsd(xmm0, qword[A1+LDA3*1-0x80]);
    vmovlps(qword[B-0x68], xmm0);
    vmovsd(xmm0, qword[A2-0x80]);
    vmovlps(qword[B-0x60], xmm0);
    vmovsd(xmm0, qword[A2+LDA*1-0x80]);
    vmovlps(qword[B-0x58], xmm0);
    vmovsd(xmm0, qword[A2+LDA*2-0x80]);
    vmovlps(qword[B-0x50], xmm0);
    vmovsd(xmm0, qword[A2+LDA3*1-0x80]);
    vmovlps(qword[B-0x48], xmm0);
    lea(A1, ptr[A1+LDA*8]);
    lea(A2, ptr[A2+LDA*8]);
    sub(B, -64);
    dec(I);
    jg(l19c, T_NEAR);
    align(4);

L(l214);
    test(M, 0x4);
    jle(l258, T_NEAR);
    vmovsd(xmm0, qword[A1-0x80]);
    vmovlps(qword[B-0x80], xmm0);
    vmovsd(xmm0, qword[A1+LDA*1-0x80]);
    vmovlps(qword[B-0x78], xmm0);
    vmovsd(xmm0, qword[A1+LDA*2-0x80]);
    vmovlps(qword[B-0x70], xmm0);
    vmovsd(xmm0, qword[A1+LDA3*1-0x80]);
    vmovlps(qword[B-0x68], xmm0);
    lea(A1, ptr[A1+LDA*4]);
    sub(B, -32);
    align(4);

L(l258);
    test(M, 0x2);
    jle(l284, T_NEAR);
    vmovsd(xmm0, qword[A1-0x80]);
    vmovlps(qword[B-0x80], xmm0);
    vmovsd(xmm0, qword[A1+LDA*1-0x80]);
    vmovlps(qword[B-0x78], xmm0);
    lea(A1, ptr[A1+LDA*2]);
    sub(B, -16);
    align(4);

L(l284);
    test(M, 0x1);
    jle(l2a0, T_NEAR);
    vmovsd(xmm0, qword[A1-0x80]);
    vmovlps(qword[B-0x80], xmm0);
    sub(B, -8);
    align(4);

L(l2a0);
    sub(N, 0x2);
    align(4);

L(l2a4);
    cmp(N, 0x1);
    jl(l3cc, T_NEAR);
    mov(A1, A);
    lea(A2, ptr[A1+LDA*4]);
    add(A, 0x4);
    mov(I, M);
    sar(I, 0x3);
    jle(l33c, T_NEAR);
    align(4);

L(l2c4);
    vmovss(xmm0, dword[A1-0x80]);
    vmovss(dword[B-0x80], xmm0);
    vmovss(xmm0, dword[A1+LDA*1-0x80]);
    vmovss(dword[B-0x7c], xmm0);
    vmovss(xmm0, dword[A1+LDA*2-0x80]);
    vmovss(dword[B-0x78], xmm0);
    vmovss(xmm0, dword[A1+LDA3*1-0x80]);
    vmovss(dword[B-0x74], xmm0);
    vmovss(xmm0, dword[A2-0x80]);
    vmovss(dword[B-0x70], xmm0);
    vmovss(xmm0, dword[A2+LDA*1-0x80]);
    vmovss(dword[B-0x6c], xmm0);
    vmovss(xmm0, dword[A2+LDA*2-0x80]);
    vmovss(dword[B-0x68], xmm0);
    vmovss(xmm0, dword[A2+LDA3*1-0x80]);
    vmovss(dword[B-0x64], xmm0);
    lea(A1, ptr[A1+LDA*8]);
    lea(A2, ptr[A2+LDA*8]);
    sub(B, -32);
    dec(I);
    jg(l2c4, T_NEAR);
    align(4);

L(l33c);
    test(M, 0x4);
    jle(l380, T_NEAR);
    vmovss(xmm0, dword[A1-0x80]);
    vmovss(dword[B-0x80], xmm0);
    vmovss(xmm0, dword[A1+LDA*1-0x80]);
    vmovss(dword[B-0x7c], xmm0);
    vmovss(xmm0, dword[A1+LDA*2-0x80]);
    vmovss(dword[B-0x78], xmm0);
    vmovss(xmm0, dword[A1+LDA3*1-0x80]);
    vmovss(dword[B-0x74], xmm0);
    lea(A1, ptr[A1+LDA*4]);
    sub(B, -16);
    align(4);

L(l380);
    test(M, 0x2);
    jle(l3ac, T_NEAR);
    vmovss(xmm0, dword[A1-0x80]);
    vmovss(dword[B-0x80], xmm0);
    vmovss(xmm0, dword[A1+LDA*1-0x80]);
    vmovss(dword[B-0x7c], xmm0);
    lea(A1, ptr[A1+LDA*2]);
    sub(B, -8);
    align(4);

L(l3ac);
    test(M, 0x1);
    jle(l3c8, T_NEAR);
    vmovss(xmm0, dword[A1-0x80]);
    vmovss(dword[B-0x80], xmm0);
    sub(B, -4);
    align(4);

L(l3c8);
    sub(N, 0x1);
    align(4);

L(l3cc);
    jmp(lc8c, T_NEAR);
    align(4);

L(l3d4);
    vxorps(xmm3, xmm3, xmm4);
    vucomiss(xmm6, xmm3);
    jne(l83c, T_NEAR);
    vmovaps(ymm6, ymm4);
    cmp(N, 0x4);
    jl(l55c, T_NEAR);
    align(4);

L(l3f0);
    mov(A1, A);
    lea(A2, ptr[A1+LDA*4]);
    add(A, 0x10);
    mov(I, M);
    sar(I, 0x3);
    jle(l4a4, T_NEAR);
    align(4);

L(l408);
    vmovups(xmm0, xword[A1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x80], xmm0);
    vmovups(xmm0, xword[A1+LDA*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x70], xmm0);
    vmovups(xmm0, xword[A1+LDA*2-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x60], xmm0);
    vmovups(xmm0, xword[A1+LDA3*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x50], xmm0);
    vmovups(xmm0, xword[A2-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x40], xmm0);
    vmovups(xmm0, xword[A2+LDA*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x30], xmm0);
    vmovups(xmm0, xword[A2+LDA*2-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x20], xmm0);
    vmovups(xmm0, xword[A2+LDA3*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x10], xmm0);
    lea(A1, ptr[A1+LDA*8]);
    lea(A2, ptr[A2+LDA*8]);
    sub(B, -128);
    dec(I);
    jg(l408, T_NEAR);
    align(4);

L(l4a4);
    test(M, 0x4);
    jle(l4f8, T_NEAR);
    vmovups(xmm0, xword[A1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x80], xmm0);
    vmovups(xmm0, xword[A1+LDA*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x70], xmm0);
    vmovups(xmm0, xword[A1+LDA*2-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x60], xmm0);
    vmovups(xmm0, xword[A1+LDA3*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x50], xmm0);
    lea(A1, ptr[A1+LDA*4]);
    sub(B, -64);
    align(4);

L(l4f8);
    test(M, 0x2);
    jle(l52c, T_NEAR);
    vmovups(xmm0, xword[A1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x80], xmm0);
    vmovups(xmm0, xword[A1+LDA*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x70], xmm0);
    lea(A1, ptr[A1+LDA*2]);
    sub(B, -32);
    align(4);

L(l52c);
    test(M, 0x1);
    jle(l54c, T_NEAR);
    vmovups(xmm0, xword[A1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x80], xmm0);
    sub(B, -16);
    align(4);

L(l54c);
    sub(N, 0x4);
    cmp(N, 0x4);
    jge(l3f0, T_NEAR);
    align(4);

L(l55c);
    cmp(N, 0x2);
    jl(l6c8, T_NEAR);
    mov(A1, A);
    lea(A2, ptr[A1+LDA*4]);
    add(A, 0x8);
    mov(I, M);
    sar(I, 0x3);
    jle(l61c, T_NEAR);
    align(4);

L(l580);
    vmovsd(xmm0, qword[A1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x80], xmm0);
    vmovsd(xmm0, qword[A1+LDA*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x78], xmm0);
    vmovsd(xmm0, qword[A1+LDA*2-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x70], xmm0);
    vmovsd(xmm0, qword[A1+LDA3*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x68], xmm0);
    vmovsd(xmm0, qword[A2-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x60], xmm0);
    vmovsd(xmm0, qword[A2+LDA*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x58], xmm0);
    vmovsd(xmm0, qword[A2+LDA*2-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x50], xmm0);
    vmovsd(xmm0, qword[A2+LDA3*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x48], xmm0);
    lea(A1, ptr[A1+LDA*8]);
    lea(A2, ptr[A2+LDA*8]);
    sub(B, -64);
    dec(I);
    jg(l580, T_NEAR);
    align(4);

L(l61c);
    test(M, 0x4);
    jle(l670, T_NEAR);
    vmovsd(xmm0, qword[A1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x80], xmm0);
    vmovsd(xmm0, qword[A1+LDA*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x78], xmm0);
    vmovsd(xmm0, qword[A1+LDA*2-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x70], xmm0);
    vmovsd(xmm0, qword[A1+LDA3*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x68], xmm0);
    lea(A1, ptr[A1+LDA*4]);
    sub(B, -32);
    align(4);

L(l670);
    test(M, 0x2);
    jle(l6a4, T_NEAR);
    vmovsd(xmm0, qword[A1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x80], xmm0);
    vmovsd(xmm0, qword[A1+LDA*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x78], xmm0);
    lea(A1, ptr[A1+LDA*2]);
    sub(B, -16);
    align(4);

L(l6a4);
    test(M, 0x1);
    jle(l6c4, T_NEAR);
    vmovsd(xmm0, qword[A1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x80], xmm0);
    sub(B, -8);
    align(4);

L(l6c4);
    sub(N, 0x2);
    align(4);

L(l6c8);
    cmp(N, 0x1);
    jl(l834, T_NEAR);
    mov(A1, A);
    lea(A2, ptr[A1+LDA*4]);
    add(A, 0x4);
    mov(I, M);
    sar(I, 0x3);
    jle(l788, T_NEAR);
    align(4);

L(l6ec);
    vmovss(xmm0, dword[A1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x80], xmm0);
    vmovss(xmm0, dword[A1+LDA*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x7c], xmm0);
    vmovss(xmm0, dword[A1+LDA*2-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x78], xmm0);
    vmovss(xmm0, dword[A1+LDA3*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x74], xmm0);
    vmovss(xmm0, dword[A2-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x70], xmm0);
    vmovss(xmm0, dword[A2+LDA*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x6c], xmm0);
    vmovss(xmm0, dword[A2+LDA*2-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x68], xmm0);
    vmovss(xmm0, dword[A2+LDA3*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x64], xmm0);
    lea(A1, ptr[A1+LDA*8]);
    lea(A2, ptr[A2+LDA*8]);
    sub(B, -32);
    dec(I);
    jg(l6ec, T_NEAR);
    align(4);

L(l788);
    test(M, 0x4);
    jle(l7dc, T_NEAR);
    vmovss(xmm0, dword[A1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x80], xmm0);
    vmovss(xmm0, dword[A1+LDA*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x7c], xmm0);
    vmovss(xmm0, dword[A1+LDA*2-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x78], xmm0);
    vmovss(xmm0, dword[A1+LDA3*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x74], xmm0);
    lea(A1, ptr[A1+LDA*4]);
    sub(B, -16);
    align(4);

L(l7dc);
    test(M, 0x2);
    jle(l810, T_NEAR);
    vmovss(xmm0, dword[A1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x80], xmm0);
    vmovss(xmm0, dword[A1+LDA*1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x7c], xmm0);
    lea(A1, ptr[A1+LDA*2]);
    sub(B, -8);
    align(4);

L(l810);
    test(M, 0x1);
    jle(l830, T_NEAR);
    vmovss(xmm0, dword[A1-0x80]);
    vxorps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x80], xmm0);
    sub(B, -4);
    align(4);

L(l830);
    sub(N, 0x1);
    align(4);

L(l834);
    jmp(lc8c, T_NEAR);
    align(4);

L(l83c);
    cmp(N, 0x4);
    jl(l9b4, T_NEAR);
    align(4);

L(l848);
    mov(A1, A);
    lea(A2, ptr[A1+LDA*4]);
    add(A, 0x10);
    mov(I, M);
    sar(I, 0x3);
    jle(l8fc, T_NEAR);
    align(4);

L(l860);
    vmovups(xmm0, xword[A1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x80], xmm0);
    vmovups(xmm0, xword[A1+LDA*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x70], xmm0);
    vmovups(xmm0, xword[A1+LDA*2-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x60], xmm0);
    vmovups(xmm0, xword[A1+LDA3*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x50], xmm0);
    vmovups(xmm0, xword[A2-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x40], xmm0);
    vmovups(xmm0, xword[A2+LDA*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x30], xmm0);
    vmovups(xmm0, xword[A2+LDA*2-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x20], xmm0);
    vmovups(xmm0, xword[A2+LDA3*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x10], xmm0);
    lea(A1, ptr[A1+LDA*8]);
    lea(A2, ptr[A2+LDA*8]);
    sub(B, -128);
    dec(I);
    jg(l860, T_NEAR);
    align(4);

L(l8fc);
    test(M, 0x4);
    jle(l950, T_NEAR);
    vmovups(xmm0, xword[A1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x80], xmm0);
    vmovups(xmm0, xword[A1+LDA*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x70], xmm0);
    vmovups(xmm0, xword[A1+LDA*2-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x60], xmm0);
    vmovups(xmm0, xword[A1+LDA3*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x50], xmm0);
    lea(A1, ptr[A1+LDA*4]);
    sub(B, -64);
    align(4);

L(l950);
    test(M, 0x2);
    jle(l984, T_NEAR);
    vmovups(xmm0, xword[A1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x80], xmm0);
    vmovups(xmm0, xword[A1+LDA*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x70], xmm0);
    lea(A1, ptr[A1+LDA*2]);
    sub(B, -32);
    align(4);

L(l984);
    test(M, 0x1);
    jle(l9a4, T_NEAR);
    vmovups(xmm0, xword[A1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovups(xword[B-0x80], xmm0);
    sub(B, -16);
    align(4);

L(l9a4);
    sub(N, 0x4);
    cmp(N, 0x4);
    jge(l848, T_NEAR);
    align(4);

L(l9b4);
    cmp(N, 0x2);
    jl(lb20, T_NEAR);
    mov(A1, A);
    lea(A2, ptr[A1+LDA*4]);
    add(A, 0x8);
    mov(I, M);
    sar(I, 0x3);
    jle(la74, T_NEAR);
    align(4);

L(l9d8);
    vmovsd(xmm0, qword[A1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x80], xmm0);
    vmovsd(xmm0, qword[A1+LDA*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x78], xmm0);
    vmovsd(xmm0, qword[A1+LDA*2-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x70], xmm0);
    vmovsd(xmm0, qword[A1+LDA3*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x68], xmm0);
    vmovsd(xmm0, qword[A2-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x60], xmm0);
    vmovsd(xmm0, qword[A2+LDA*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x58], xmm0);
    vmovsd(xmm0, qword[A2+LDA*2-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x50], xmm0);
    vmovsd(xmm0, qword[A2+LDA3*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x48], xmm0);
    lea(A1, ptr[A1+LDA*8]);
    lea(A2, ptr[A2+LDA*8]);
    sub(B, -64);
    dec(I);
    jg(l9d8, T_NEAR);
    align(4);

L(la74);
    test(M, 0x4);
    jle(lac8, T_NEAR);
    vmovsd(xmm0, qword[A1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x80], xmm0);
    vmovsd(xmm0, qword[A1+LDA*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x78], xmm0);
    vmovsd(xmm0, qword[A1+LDA*2-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x70], xmm0);
    vmovsd(xmm0, qword[A1+LDA3*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x68], xmm0);
    lea(A1, ptr[A1+LDA*4]);
    sub(B, -32);
    align(4);

L(lac8);
    test(M, 0x2);
    jle(lafc, T_NEAR);
    vmovsd(xmm0, qword[A1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x80], xmm0);
    vmovsd(xmm0, qword[A1+LDA*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x78], xmm0);
    lea(A1, ptr[A1+LDA*2]);
    sub(B, -16);
    align(4);

L(lafc);
    test(M, 0x1);
    jle(lb1c, T_NEAR);
    vmovsd(xmm0, qword[A1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovlps(qword[B-0x80], xmm0);
    sub(B, -8);
    align(4);

L(lb1c);
    sub(N, 0x2);
    align(4);

L(lb20);
    cmp(N, 0x1);
    jl(lc8c, T_NEAR);
    mov(A1, A);
    lea(A2, ptr[A1+LDA*4]);
    add(A, 0x4);
    mov(I, M);
    sar(I, 0x3);
    jle(lbe0, T_NEAR);
    align(4);

L(lb44);
    vmovss(xmm0, dword[A1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x80], xmm0);
    vmovss(xmm0, dword[A1+LDA*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x7c], xmm0);
    vmovss(xmm0, dword[A1+LDA*2-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x78], xmm0);
    vmovss(xmm0, dword[A1+LDA3*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x74], xmm0);
    vmovss(xmm0, dword[A2-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x70], xmm0);
    vmovss(xmm0, dword[A2+LDA*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x6c], xmm0);
    vmovss(xmm0, dword[A2+LDA*2-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x68], xmm0);
    vmovss(xmm0, dword[A2+LDA3*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x64], xmm0);
    lea(A1, ptr[A1+LDA*8]);
    lea(A2, ptr[A2+LDA*8]);
    sub(B, -32);
    dec(I);
    jg(lb44, T_NEAR);
    align(4);

L(lbe0);
    test(M, 0x4);
    jle(lc34, T_NEAR);
    vmovss(xmm0, dword[A1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x80], xmm0);
    vmovss(xmm0, dword[A1+LDA*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x7c], xmm0);
    vmovss(xmm0, dword[A1+LDA*2-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x78], xmm0);
    vmovss(xmm0, dword[A1+LDA3*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x74], xmm0);
    lea(A1, ptr[A1+LDA*4]);
    sub(B, -16);
    align(4);

L(lc34);
    test(M, 0x2);
    jle(lc68, T_NEAR);
    vmovss(xmm0, dword[A1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x80], xmm0);
    vmovss(xmm0, dword[A1+LDA*1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x7c], xmm0);
    lea(A1, ptr[A1+LDA*2]);
    sub(B, -8);
    align(4);

L(lc68);
    test(M, 0x1);
    jle(lc88, T_NEAR);
    vmovss(xmm0, dword[A1-0x80]);
    vmulps(xmm0, xmm6, xmm0);
    vmovss(dword[B-0x80], xmm0);
    sub(B, -4);
    align(4);

L(lc88);
    sub(N, 0x1);
    align(4);

L(lc8c);

    postamble();
}
outLocalLabel();

#undef M
#undef N
#undef A
#undef LDA
#undef ALPHA
#undef B
#undef I
#undef A1
#undef A2
#undef LDA3
#ifdef _WIN32
#undef ARG_ALPHA
#undef ARG_B
#endif
}

}
}
}
